<?php

declare( strict_types = 1 );

namespace App\Common\Model\Base\DataUnit\JoinModel;

use App\Common as com;
use App\Common\Model\Base\DataUnit\JoinModel\Item as nameItem;
use App\Common\Model as nameModel;
use App\Common\Model\Base as nameModelBase;

/**
 * @method nameModel\Base\DataUnit goDataUnit_DEL
 */
class Item extends nameModelBase\DataUnit {

	/**
	 * 示例：['id', 'id2']
	 * @var array|null
	 */
	protected ?array $_joinConfig_AtoB = null;

	/**
	 * 示例：''
	 * @var string|null
	 */
	private ?string $_joinConfig_EchoSite = null;

	private ?com\Lib\Db\Join $_dbJoin = null;

	private $_dataHelp;

	/**
	 * 是否存在
	 * @var bool|null [true]存在 [false]不存在 [null]未判断
	 */
	private ?bool $_isExistDataHelp = null;

	/**
	 * 是否为连接多条数据
	 * @var bool
	 */
	private bool $isJoinMore = false;

	private array $_option = [
		'isCleanIncompleteData' => null,
	];


	/**
	 * Base constructor.
	 * @param nameModelBase\DataUnit $parentDataUnit
	 * @throws
	 */
	public function __construct( nameModelBase\DataUnit $parentDataUnit ) {
		parent::__construct();
		//
		$this->goWeakReferencePool()->create( 'parentDataUnit', $parentDataUnit );
		//
		$this->setEchoSite();
		//
		$this->initDataUnitParam();
		//
		$this->callInit();
	}

	/**
	 * @return nameModelBase\DataUnit
	 * @throws
	 */
	protected function getParentDataUnit(  ):nameModelBase\DataUnit {
		return $this->goWeakReferencePool()->get( 'parentDataUnit' );
	}

	/**
	 * 执行init
	 */
	private function callInit() {
		if( method_exists( $this, '_init' ) ){
			call_user_func( [
				$this,
				'_init'
			] );
		}
	}


	/**
	 * 初始化dataUnit参数
	 * @return void
	 */
	protected function initDataUnitParam():void {
		// 自动清理
		if( $this->goOption()->getIsCleanIncompleteData() === null && $this->goOption()->getIsCleanIncompleteData() ){
			$this->goOption()->setIsCleanIncompleteData( true );
		}
		// 缓存
		if( $this->goOption()->getIsGlogalCache() === null && $this->getCacheTime() !== null ){
			$this->cacheExpire( $this->getCacheTime() );
		}
	}

	/**
	 * 是否存在dataHelp
	 * @return bool
	 */
	private function isExistDataHelp():bool {
		if( $this->_isExistDataHelp === null ){
			$classPath = static::class . "\DataHelp";
			$this->_isExistDataHelp = class_exists( $classPath );
		}
		//
		return $this->_isExistDataHelp;
	}

	/**
	 * 是否为连接多条数据
	 * @param bool $isJoinMore
	 * @return $this
	 */
	public function setJoinMore( bool $isJoinMore = true ):self {
		$this->isJoinMore = $isJoinMore;
		//
		return $this;
	}

	/**
	 * dataHelp
	 * @return nameItem\DataHelp
	 * @throws
	 */
	public function goDataHelp():nameItem\DataHelp {
		if( ! isset( $this->_dataHelp ) ){
			if( ! $this->isExistDataHelp() ){
				throw com\Lib\Err\Exception::makeOfNew( 'DataHelp', com\Lib\Err\Code::$sysFileNotExist );
			}
			//
			$classPath = static::class . "\DataHelp";
			$this->_dataHelp = new $classPath( $this );
		}
		//
		return $this->_dataHelp;
	}

	/**
	 * 获取输出位置
	 * @return string
	 */
	public function getEchoSite():string {
		return $this->_joinConfig_EchoSite;
	}

	/**
	 * 设置输出位置
	 * @param null $echoSite 输出位置。[{null}]默认格式（joinXxx）
	 * @return $this
	 */
	public function setEchoSite( $echoSite = null ):self {
		if( $echoSite === null ){
			$this->_joinConfig_EchoSite = 'join' . com\Lib\Fun\Class_::getClassBasename( static::class );
		} else{
			$this->_joinConfig_EchoSite = $echoSite;
		}
		//
		return $this;
	}

	/**
	 * 设置默认数据
	 * @param mixed $defaultData 默认数据
	 * @return $this
	 */
	public function defaultData( mixed $defaultData = [] ):self {
		$this->goDbJoin()->defaultData( $defaultData );
		//
		return $this;
	}

	/**
	 * 获取join对象
	 * @return com\Lib\Db\Join
	 */
	public function goDbJoin():com\Lib\Db\Join {
		if( $this->_dbJoin === null ){
			$this->_dbJoin = new com\Lib\Db\Join( [] );
			// _mainTable.
		}
		//
		return $this->_dbJoin;
	}

	/**
	 * [事件]获取数据之前
	 * @return void
	 */
	public function eventDataBeforeOfJoin():void {
		// d(get_class($this->dataStore->main));
		//
		//
		$this->getParentDataUnit()->hasFieldOrAdd( $this->_joinConfig_AtoB[0], isRetain: false );
//		if( ! empty( $this->goModelQuery()->getQuery()->columns ) ){
//			$this->addField( $this->_joinConfig_AtoB[ 0 ], true );
//		}
	}

	/**
	 * [事件]获取数据之后
	 * @param array &$dataQuote 源数据
	 * @return void
	 * @throws
	 */
	public function eventDataLaterOfJoin( array &$dataQuote ):void {
		// ...
		if( empty( $dataQuote ) || empty( $dataQuote[0] ) ){
			return;
		}
		// 初始化dataUnit参数
		if( $this->goOption()->getIsCleanIncompleteData() === null && $this->getIsCleanIncompleteData() ){
			$this->goOption()->setIsCleanIncompleteData( true );
		}
		//
		$dbJoin = $this->goDbJoin()->sourceData( $dataQuote )->sourceMore( true )->setJoinFieldA( $this->getFieldActualName( $this->_joinConfig_AtoB[0] ) );
		// 输出位置
		if( $dbJoin->getEchoSite() === null ){
			$dbJoin->setEchoSite( $this->getEchoSite() );
		}
		// 清理不完整的数据
		if( $this->getIsCleanIncompleteData() ){
			$dbJoin->isDeleteSourceOfJoinEmpty( true );
		}
		//
		if( ! $this->isJoinMore ){
			$dataQuote = $dbJoin->joinOne( $this, $this->_joinConfig_AtoB[1] );
		} else{
			$dataQuote = $dbJoin->joinMore( $this, $this->_joinConfig_AtoB[1] );
		}
		//
		if( $this->isExistDataHelp() ){
			$this->goDataHelp()->exc( $dataQuote );
		}
	}

	/**
	 * 获取"是否清理不完整的数据"
	 * @return bool
	 */
	public function getIsCleanIncompleteData():bool {
		if( $this->_option['isCleanIncompleteData'] !== null ) return $this->_option['isCleanIncompleteData'];
		//
		return $this->getParentDataUnit()->goOption()->getIsCleanIncompleteData();
	}

	/**
	 * 设置"是否清理不完整的数据"
	 * @param bool $isCleanIncompleteData
	 * @return $this
	 */
	public function setIsCleanIncompleteData( bool $isCleanIncompleteData = true ):self {
		$this->_option['isCleanIncompleteData'] = $isCleanIncompleteData;
		//
		return $this;
	}

	/**
	 * @param $dataQuote
	 * @return mixed 变量地址
	 * @throws
	 */
	public function &getJoinDataQuote( &$dataQuote ):array {
		return com\Lib\Fun\Array_::extractAssignValue( $dataQuote, $this->goDbJoin()->getEchoSite(), [ 'returnQuote' => 1 ] );
	}

	protected function dataDealExc( array &$dataQuote, bool $isMore = false ) {
	}

}
